﻿#define _CRT_SECURE_NO_WARNINGS

//#include <stdio.h>
//int main()
//{
//	int num, arr[10], i = 0;
//	scanf("%d", &num);
//	while (num)
//	{
//		int t = num % 10;
//		t = (t + 5) % 10;
//		arr[i++] = t;
//		num /= 10;
//	}
//
//	for (int j = i - 1; j >= 0; j--)
//		printf("%d", arr[j]);
//	return 0;
//}
// 
// 

//#include <iostream>
////using std::cout;
//
//using namespace std;
//int main()
//{
//	int a = 5;
//	int& b = a;
//	cout << &a << " " << & b << endl;//引用即取别名，内存地址是一样的
//
//	//引用一旦引用一个实体，再不能引用其他实体
//	int x = 10;
//	a = x;//并没有改变引用，只是赋值。
//
//	cout << a << " " << b << endl;
//	return 0;
//}

//引用做参数（减少拷贝提高效率）（大对象/深拷贝类对象）
//#include <iostream>
//using namespace std;
//
//void swap1(int x, int y)
//{
//	int temp = x;
//	x = y;
//	y = temp;
//}
//
//void swap2(int* x, int* y)
//{
//	int temp = *x;
//	*x = *y;
//	*y = temp;
//}
//
//void swap3(int& x, int& y)
//{
//	int temp = x;
//	x = y;
//	y = temp;
//}
//int main()
//{
//	int a = 1, b = 2;
//	//传值
//	cout << "a = " << a << " " << "b = " << b << endl;
//	swap1(a, b);
//	cout << "a = " << a << " " << "b = " << b << endl;
//
//	//指针传参（C语言）
//	cout << "a = " << a << " " << "b = " << b << endl;
//	swap2(&a, &b);
//	cout << "a = " << a << " " << "b = " << b << endl;
//
//	//引用做参数
//	cout << "a = " << a << " " << "b = " << b << endl;
//	swap3(a, b);
//	cout << "a = " << a << " " << "b = " << b << endl;
//	return 0;
//}


//（减少拷贝提高效率）（大对象 / 深拷贝类对象--什么是深拷贝以后会讲）



//typedef struct ListNode
//{
//	int val;
//	pNode next;//cpp可以这么写，C不可以
//}Node, *pNode;

//等价于
//typedef struct ListNode Node;
//typedef struct Node* pNode;

//我们一般写链表的尾插的时候，如果返回值是void，那么参数应该是结构体的二级指针，
//实参传递的时候，一般都是&ps这种，是结构体一级指针类型，Node** head-> pNode* head-> pNode& head（取别名，引用） 
//void LTPushBack(pNode& phead, int x);



//typedef struct A
//{
//	int a[2000];
//}A;
//
////效率问题
////拷贝
//
////​​test1(a)（传值调用）​​：
////每次调用都会在栈上复制整个 A 结构体（800KB）。
////10000 次循环 = 8GB 数据拷贝（非常低效）。
//
////​​test2(a)（传引用）​​：
////只传递指针（8字节），没有数据拷贝。
////10000 次循环 = 80KB 数据传递（高效）
//void test1(A a)
//{
//	
//}
//
////不需要拷贝
//void test2(A& a)
//{
//	
//}
//
//void TestRefAndValue()
//{
//	A a;
//	// 以值作为函数参数
//	size_t begin1 = clock();
//	for (size_t i = 0; i < 10000; ++i)
//		test1(a);
//	size_t end1 = clock();
//
//	// 以引用作为函数参数
//	size_t begin2 = clock();
//	for (size_t i = 0; i < 10000; ++i)
//		test2(a);
//	size_t end2 = clock();
//
//	// 分别计算两个函数运行结束后的时间
//	cout << "TestFunc1(A)-time:" << end1 - begin1 << endl;
//	cout << "TestFunc2(A&)-time:" << end2 - begin2 << endl;
//}
//
//
//int main()
//{
//	TestRefAndValue();
//	return 0;
//}



////引用做返回值  （减少拷贝提高效率）（大对象/深拷贝类对象--什么是深拷贝以后会讲）
////引用做返回值   修改返回值+获取返回值（权限）
////做返回值
//#include <iostream>
//using namespace std;
////传值返回
//int count()
//{
//	static int n = 0;
//	n++;
//	return n;
//}
//
//int main()
//{
//	//并不是直接把值返回给ret，栈帧销毁的时候，先把数据放在临时变量里面，再赋值给ret
//	int ret = count();
//
//	return 0;
//}

//传引用返回
//int& Count()
//{
//	//返回的时候，n并没有被销毁
//	static int n = 0;
//	n++;
//	return n;
//}
//
//int main()
//{
//	int ret = Count();
//	cout << ret << endl;
//	return 0;
//}

//不安全
//int& Count()
//{
//	int n = 0;
//	n++;
//	return n;
//}
//
//int main()
//{
//	int ret = Count();
//	cout << ret << endl;
//
//	return 0;
//}

//#include <iostream>
//#include <ctime>
//#include <cassert>
//using namespace std;
//
//int& Count(int x)
//{
//	int n = x;
//	n++;
//	return n;
//}
//
//int main()
//{
//	int& ret = Count(10);
//	cout << ret << endl;
//
//	rand();
//
//	Count(20);
//	cout << ret << endl;
//
//	return 0;
//}

// 错误样例：不能用引用
//int& Count(int x)
//{
//	int n = x;
//	n++;
//	// ...
//	return n;
//}

// 正确样例：可以用引用
//int& Count(int x)
//{
//	static int n = x;
//	n++;
//	// ...
//	return n;
//}



//typedef struct SeqList
//{
//	int a[100];
//	size_t size;
//}SeqList, *pSeqList;
//
//int SLGet(pSeqList ps, int pos)
//{
//	assert(pos < 100 && pos >= 0);
//
//	return ps->a[pos];
//}
//
//void SLModify(pSeqList ps, int pos, int x)
//{
//	assert(pos < 100 && pos >= 0);
//
//	ps->a[pos] = x;
//}
//
//int& SLAt(SeqList& s, int pos)
//{
//	assert(pos < 100 && pos >= 0);
//
//	return s.a[pos];
//}
//
//int main()
//{
//	
//
//	SeqList s;
//	SLModify(&s, 0, 1);
//	cout << SLGet(&s, 0) << endl;
//
//	// 对第0个位的值+5
//	int ret1 = SLGet(&s, 0);
//	SLModify(&s, 0, ret1+5);
//
//
//	SLAt(s, 0) = 5;
//	cout << SLAt(s, 0) << endl;
//	
//	SLAt(s, 0) += 5;
//
//	return 0;
//}

//struct SeqList
//{
//	int a[100];
//	size_t size;
//
//	int& at(int pos)
//	{
//		assert(pos >= 0 && pos < 100);
//		return a[pos];
//	}
//
//	int& operator[](int pos)
//	{
//		assert(pos >= 0 && pos < 100);
//		return a[pos];
//	}
//};



//int main()
//{
//	SeqList s;
//	s.at(0) = 0;
//	s.at(0)++;
//	cout << s.at(0) << endl;
//
//	s[1] = 10;
//	s[1]++;
//	cout << s[1] << endl;
//
//	/*vector<int> v;
//	for (int i = 0; i < v.size(); ++i)
//	{
//		v[i]++;
//	}*/
//
//	return 0;
//}


//int main()
//{
//	// 不可以
//	// 引用过程中，权限不能放大
//	const int a = 0;
//	//int& b = a;
//
//	// 可以，c拷贝给d，没有放大权限，因为d的改变不影响c
//	const int c = 0;
//	int d = c;
//
//	// 不可以
//	// 引用过程中，权限可以平移或者缩小
//	int x = 0;
//	int& y = x;
//	const int& z = x;
//	++x;
//	++y;
//
//	cout << z << endl;
//	//++z;
//
//	//常值引用
//	const int& m = 10;
//
//	double dd = 1.11;
//	int ii = dd;
//
//	const int& rii = dd;
//
//	return 0;
//}
//
//
//int func1()
//{
//	static int x = 0;
//	return x;
//}
//
//int& func2()
//{
//	static int x = 0;
//	return x;
//}
//
//int main()
//{
//	//int& ret1 = func1();  // 权限放大
//	//const int& ret1 = func1(); // 权限平移
//	// int ret1 = func1();  // 拷贝
//
//	int& ret2 = func2();		// 权限平移
//	const int& rret2 = func2();  // 权限缩小
//
//	return 0;
//}


//int main()
//{
//	int i = 1;
//	double j = 1.1;
//	if (j > i)
//	{
//		cout << "xxxxx" << endl;
//	}
//
//	return 0;
//}

//int main()
//{
//	int a = 10;
//
//	// 语法层面：不开空间，是对a取别名
//	int& ra = a;
//	ra = 20;
//
//	// 语法层面：开空间，存储a的地址
//	int* pa = &a;
//	*pa = 30;
//
//	return 0;
//}


#include <string>
#include <vector>
#include <map>
#include <iostream>
using namespace std;
//
//int main()
//{
//	auto a = 11;
//	auto b = "jsdgferyf";
//	auto c = 5.3;
//	cout << typeid(a).name() << endl;
//	cout << typeid(b).name() << endl;
//	cout << typeid(c).name() << endl;
//}


//int main()
//{
//	int a = 0;
//	int b = a;
//	auto c = a; // 根据右边的表达式自动推导c的类型
//	auto d = 1 + 1.11; // 根据右边的表达式自动推导d的类型
//	cout << typeid(c).name() << endl;
//	cout << typeid(d).name() << endl;
//
//	vector<int> v;
//
//	// 类型很长
//	//vector<int>::iterator it = v.begin();
//	// 等价于
//	auto it = v.begin();
//
//	std::map<std::string, std::string> dict;
//	//std::map<std::string, std::string>::iterator dit = dict.begin();
//	// 等价于
//	auto dit = dict.begin();
//
//	return 0;
//}


//int main()
//{
//	//int arr[] = { 1, 2, 3, 4, 5 };
//
//	//for (int i = 0; i < sizeof(arr) / sizeof(int); ++i)
//	//	arr[i] *= 2;
//
//	//for (int* p = arr; p < arr + sizeof(arr) / sizeof(arr[0]); ++p)
//	//	cout << *p << " ";
//	//cout << endl;
//
//	//// 适用于数组
//	//// 范围for 语法糖
//	//// 依次取数组中数据赋值给e
//	//// 自动迭代，自动判断结束
//	//// for (int x : arr)
//	//for (auto x : arr)
//	//{
//	//	cout << x << " ";
//	//}
//	//cout << endl;
//
//	//// 修改数据
//	//for (auto& e : arr)
//	//{
//	//	e *= 2;
//	//}
//
//	//for (auto e : arr)
//	//{
//	//	cout << e << " ";
//	//}
//	//cout << endl;
//
//	int arr[] = { 1,2,5,6,9,5,4,7,8,5,6,9 };
//	/*for (auto e : arr)
//		cout << e << " ";
//	cout << endl;*/
//
//	for (auto& e : arr)
//	{
//		e *= 2;
//		cout << e << " ";
//	}
//
//	cout << endl;
//	return 0;
//}

//// ljt是命名空间的名字，一般开发中是用项目名字做命名空间名。
//// 1. 正常的命名空间定义
//namespace ljt
//{
//	// 命名空间中可以定义变量/函数/类型
//	int rand = 10;
//	int Add(int left, int right)
//	{
//		return left + right;
//	}
//
//	struct Node
//	{
//		struct Node* next;
//		int val;
//	};
//}
////2. 命名空间可以嵌套
//// test.cpp
//namespace N1
//{
//	int a;
//	int b;
//	int Add(int left, int right)
//	{
//		return left + right;
//	}
//	namespace N2
//	{
//		int c;
//		int d;
//		int Sub(int left, int right)
//		{
//			return left - right;
//		}
//	}
//}
////3. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。
//// ps：一个工程中的test.h和上面test.cpp中两个N1会被合并成一个
//// test.h
//namespace N1
//{
//	int Mul(int left, int right)
//	{
//		return left * right;
//	}
//}

//#include <stdio.h>
//#include <stdlib.h>
//int rand = 10;
//// C语言没办法解决类似这样的命名冲突问题，所以C++提出了namespace来解决
//int main()
//{
//	printf("%d\n", rand);
//	return 0;
//}
//// 编译后后报错：error C2365: “rand”: 重定义；以前的定义是“函数”



//namespace ljt
//{
//	// 命名空间中可以定义变量/函数/类型
//	int a = 0;
//	int b = 1;
//	int Add(int left, int right)
//	{
//		return left + right;
//	}
//	struct Node
//	{
//		struct Node* next;
//		int val;
//	};
//}
//int main()
//{
//	// 编译报错：error C2065: “a”: 未声明的标识符
//	printf("%d\n", a);
//	return 0;
//}


//int main()
//{
//	int a = 10;
//	int& ra = a;
//	cout << "&a = " << &a << endl;
//	cout << "&ra = " << &ra << endl;
//	return 0;
//}

//int main()
//{
//	int a = 10;
//	int& ra = a;
//	ra = 20;
//	int* pa = &a; *pa = 20;
//	return 0;
//}